/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fourplay.frontEnd;

import fourplay.constants.Constants;

/**
 * State that has the board and other methods for evaluating and
 * modifying the board.
 *
 * Board is stored as a 2D array and is as follows.
 *
 * 0,0   -> 0, num_col
 *
 * |                |
 * |                |
 *
 * num_rows, 0  -> num_rows, num_col
 *
 *
 * @author CJ
 */
public class State{

    protected char board[][];


    public State(){
        board = new char[Constants.NUM_ROWS][Constants.NUM_COL];
        resetBoard();
    }

    public void resetBoard(){
        for(int i = 0; i < board.length; ++i){
            for(int j = 0; j < board[i].length; ++j){
                board[i][j] = Constants.EMPTY;
            }
        }
    }

    public State clone(){
        State result = new State();
        for(int row = 0; row < this.board.length; ++row){
            for(int col = 0; col < this.board[row].length; ++col){
                result.board[row][col] = this.board[row][col];
            }
        }
        return result;
    }

    public char[][] getBoard(){
        return this.board;
    }

    public String toString(){
        String result = new String();
        for(int i = 0; i < board.length; ++i){
            for(int j = 0; j < board[i].length; ++j){
                result = result + "| " + board[i][j] + " ";
            }
            result += "|\n";
        }
        for(int i = 1; i < board[0].length + 1; ++i){
            result += "  " + i + " ";
        }
        result += '\n';

        return result;
    }

    /** Assumes Col is legal and attempts to place the computer's symbol
     * in the desired col.
     *
     * @param col
     * @return -1 if adding was not successful.
     */
    public int addComputer(int col){
        return addToCol(col, Constants.COMP_SYM);
    }

    /**
     * Assumes Col is legal and attempts to place the player's symbol
     * in the desired col.
     * @param col
     * @return -1 is adding was not successful.
     */
    public int addPlayer(int col){
        return addToCol(col, Constants.PLAY_SYM);
    }

    /** Assumes Col is legal and attempts to place the symbol in the
     * desired col.
     *
     * @param col
     * @param symbol to be added to col
     * @return -1 if adding was not successful
     */
    public int addToCol(int col, char symbol){
        for(int i = this.board.length - 1; i >= 0; --i){
            if(this.board[i][col] == Constants.EMPTY){
                this.board[i][col] = symbol;
                return 0;
            }
        }
        return -1;
    }

    /**
     * Returns the symbol of the winner of the game if there is one.
     * Returns the empty symbol if there is no current winner.
     * @return Symbol of winner, empty symbo if there is no current winner.
     */
    public char getWinner(){
        //Purpose.. go col by col and check down -> right -> up diagonal -> down diagonal

        boolean full = true;

        //Check Down
        for(int i = 0; i < this.board[0].length; ++i){
            for(int j = 0; j < this.board.length -3; ++j){
                int count = 1;
                if(this.board[j][i] == Constants.EMPTY){
                    full = false;
                    continue;
                }
                for(int k = j + 1; k < this.board.length && k < j + 4; ++k){
                    if(this.board[k][i] == this.board[j][i])
                        count++;
                    if(count == 4)
                        return this.board[k][i];
                }
            }
        }

        //Check Right
        for(int i = 0; i < this.board[0].length - 3; ++i){
            for(int j = 0; j < this.board.length; ++j){
                int count = 1;
                if(this.board[j][i] == Constants.EMPTY){
                    full = false;
                    continue;
                }
                for(int k = i + 1; k < this.board[j].length && k < i + 4; ++k){
                    if(this.board[j][k] == this.board[j][i])
                        count++;
                    if(count == 4)
                        return this.board[j][i];
                }
            }
        }

        //Up diagnol
        for(int i = 0; i < this.board[0].length - 3; ++i){
            for(int j = 3; j < this.board.length; ++j){
                int count = 1;
                if(this.board[j][i] == Constants.EMPTY){
                    full = false;
                    continue;
                }
                int row = j - 1;
                for(int col = i + 1;col < i + 4 && row > -1; ++col){
                    if(this.board[row][col] == this.board[j][i])
                        count++;
                    if(count == 4)
                        return this.board[j][i];
                    --row;
                }
            }
        }

        //Down Diagonal
        for(int i = 0; i < this.board[0].length - 3; ++i){
            for(int j = 0; j < this.board.length - 3; ++j){
                int count = 1;
                if(this.board[j][i] == Constants.EMPTY){
                    full = false;
                    continue;
                }
                int row = j + 1;
                for(int col = i + 1; col < i + 4 && row < j + 4; ++col){
                    if(this.board[row][col] == this.board[j][i])
                        count++;
                    if(count == 4)
                        return this.board[j][i];
                    ++row;
                }

            }
        }

        if(full)
            return Constants.CATS_GAME;

        return Constants.EMPTY;
    }

}
